import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, TreeRepository } from 'typeorm';
import { Menu } from './menu.entity';
import { CasbinService } from '../casbin/casbin.service';

@Injectable()
export class MenuService {
  constructor(
    @InjectRepository(Menu)
    private menuRepository: TreeRepository<Menu>,
    private casbinService: CasbinService,
  ) {}

  async findAll(): Promise<Menu[]> {
    return await this.menuRepository.find();
  }

  async findTree(): Promise<Menu[]> {
    return await this.menuRepository.findTrees();
  }

  async findOne(id: number): Promise<Menu | null> {
    return await this.menuRepository.findOne({ where: { id } });
  }

  async create(menuData: Partial<Menu>): Promise<Menu> {
    const menu = this.menuRepository.create(menuData);
    return await this.menuRepository.save(menu);
  }

  async update(id: number, menuData: Partial<Menu>): Promise<Menu | null> {
    await this.menuRepository.update(id, menuData);
    return await this.menuRepository.findOne({ where: { id } });
  }

  async remove(id: number): Promise<void> {
    await this.menuRepository.delete(id);
  }

  // 获取所有启用的菜单并构建成树形结构
  async getEnabledMenuTree(): Promise<Menu[]> {
    const menus = await this.menuRepository.find({
      where: { status: 1 },
      order: { orderNum: 'ASC' }
    });
    
    // 构建树形结构
    const menuMap = new Map<number, Menu>();
    const rootMenus: Menu[] = [];
    
    // 先将所有菜单放入map中
    menus.forEach(menu => {
      menu.children = [];
      menuMap.set(menu.id, menu);
    });
    
    // 构建父子关系
    menus.forEach(menu => {
      if (menu.parentId === 0) {
        rootMenus.push(menu);
      } else {
        const parent = menuMap.get(menu.parentId);
        if (parent && parent.children) {
          parent.children.push(menu);
        }
      }
    });
    
    return rootMenus;
  }
  
  async buildMenuTree(menus: Menu[]): Promise<Menu[]> {
    // 构建树形结构
    const menuMap = new Map<number, Menu>();
    const rootMenus: Menu[] = [];

    // 先将所有菜单放入map中
    menus.forEach(menu => {
      if (!menu.children) {
        menu.children = [];
      }
      menuMap.set(menu.id, menu);
    });

    // 构建父子关系
    menus.forEach(menu => {
      if (menu.parentId === 0) {
        rootMenus.push(menu);
      } else {
        const parent = menuMap.get(menu.parentId);
        if (parent && parent.children) {
          parent.children.push(menu);
        }
      }
    });

    return rootMenus;
  }
  
  async filterMenusByPermissions(menus: Menu[], user: any): Promise<Menu[]> {
    
    // 对于普通用户，根据Casbin策略过滤菜单
    const filteredMenus: Menu[] = [];
    
    for (const menu of menus) {
      // 只处理启用的菜单
      if (menu.status !== 1) {
        continue;
      }
      
      // 如果菜单没有设置权限标识，则默认不可见
      if (!menu.permission || menu.permission.trim() === '') {
        continue;
      }
      
      // 检查用户是否有访问此菜单的权限
      const hasPermission = await this.casbinService.enforce(user, menu.permission, 'read');
      if (hasPermission) {
        filteredMenus.push(menu);
      }
    }

    return filteredMenus;
  }

  async delete(id: number): Promise<void> {
    await this.menuRepository.delete(id);
  }
}